package com.linshidream.intrachat.simplenio.pipeline.hearbeat;

import com.linshidream.intrachat.simplenio.pipeline.context.MiniHandlerContext;
import com.linshidream.intrachat.simplenio.pipeline.handler.MiniChannelInboundHandler;

/**
 * Created on 2025/8/21 18:30
 *
 * @author linshidream
 * @version 1.0.0
 * @description
 */

public class HeartbeatHandler implements MiniChannelInboundHandler {

    private int missedHeartbeats = 0;

    /**
     * 最大失连次数
     */
    private final int maxMissed;

    public HeartbeatHandler(int maxMissed) {
        this.maxMissed = maxMissed;
    }

    @Override
    public void channelRead(MiniHandlerContext ctx, Object msg) {
        if (HearbeatState.PONG.getState().equals(msg)) {
            System.out.println("[HeartbeatHandler] 心跳服务收到 PONG ,心跳次数恢复");
            // 接收到 PONG 心跳次数恢复
            missedHeartbeats = 0;
        } else {
            ctx.fireChannelRead(msg);
        }
    }

    @Override
    public void userEventTriggered(MiniHandlerContext ctx, Object evt) {
        if (evt instanceof MiniIdleState) {
            MiniIdleState idleState = (MiniIdleState) evt;
            if (MiniIdleState.WRITE_IDLE.equals(idleState)) {
                // 长时间没有写，没有触发写事件，超时了发送心跳
                System.out.println("[HeartbeatHandler] 心跳服务收到写空闲事件，尝试发送 PING ");

                ctx.channel().write(HearbeatState.PING.getState());
            } else if (MiniIdleState.READ_IDLE.equals(idleState)) {
                missedHeartbeats++;
                System.out.println("[HeartbeatHandler] 心跳服务收到读空闲事件，当前心跳次数" + missedHeartbeats);

                if (missedHeartbeats >= maxMissed) {
                    System.out.println("[HeartbeatHandler] 心跳服务收到读空闲事件，当前心跳次数" + missedHeartbeats + ", 连接失效，关闭通道...");
                    // 关闭通道
                    ctx.fireChannelInactive();
                }
            }
        } else {
            ctx.fireUserEventTriggered(evt);
        }
    }
}
